package net.sf.rose.jdbc.query;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import net.sf.rose.jdbc.ConstantCode;
import net.sf.rose.jdbc.PageBean;
import net.sf.rose.jdbc.bean.DataAuthorBean;
import net.sf.rose.jdbc.bean.DbUserBean;
import net.sf.rose.jdbc.bean.FieldBean;
import net.sf.rose.jdbc.bean.ModelBean;
import net.sf.rose.jdbc.bean.TableBean;
import net.sf.rose.jdbc.bean.annotation.Table;
import net.sf.rose.jdbc.service.Service;
import net.sf.rose.util.BeanWrapper;
import net.sf.rose.util.DateFormat;
import net.sf.rose.util.RoseRuntimeException;

/**
 * 类说明：自动拼接SQL语句
 * 
 * @author fengjian
 * @since 2013/05/18
 */
public class QuerySQL {

	/** 执行数据库操作用的SQL语句 */
	protected StringBuilder sql = null;

	/** 执行数据库操作用的SQL语句排序部分 */
	protected List<String[]> orderby = new java.util.ArrayList<>();

	/** 执行数据库操作用的参数 */
	protected List<Object> list = new java.util.ArrayList<>();

	/** 分页参数 */
	protected PageBean page = null;

	/** 数据库名 */
	protected String databaseName = null;

	/** 实体类型 */
	protected Class<?> entityClass;

	/** 数据库表名 */
	protected String tableName = null;

	/**
	 * 构造函数 如果监听更新数据，则创建缓存元数据类
	 */
	public QuerySQL() {
		super();
	}

	/**
	 * 功能:设置数据库操作用的参数
	 * 
	 * @param sql - SQL语句
	 * @return SQL语句
	 */
	public StringBuilder setSQL(String sql) {
		this.sql = new StringBuilder(sql);
		this.list.clear();
		this.orderby.clear();
		return this.sql;
	}

	/**
	 * 功能:仅更新SQL语句
	 * 
	 * @param sql - SQL语句
	 * @return SQL语句
	 */
	public StringBuilder updateSQL(String sql) {
		this.sql = new StringBuilder(sql);
		return this.sql;
	}

	/**
	 * 功能:返回执行数据库操作用的SQL语句
	 * 
	 * @return SQL语句
	 */
	public String getSql() {
		return this.sql.toString();
	}

	/**
	 * 功能:返回SQL语句
	 * 
	 * @return SQL语句
	 */
	public StringBuilder getSqlBuffer() {
		return this.sql;
	}

	/**
	 * 功能:准备SQL语句
	 */
	public void prepareSql() {
		int i = this.sql.indexOf(" WHERE ");
		int j = this.sql.indexOf(" where ");
		// 如果SQL语句中没有条件起始符
		if (i == -1 && j == -1) {
			// 如果有AND条件标记
			int index = this.sql.indexOf(" AND ");
			if (index != -1) {
				this.sql.replace(index, index + 5, " WHERE ");
			} else {
				index = this.sql.indexOf(" and ");
				if (index != -1) {
					this.sql.replace(index, index + 5, " where ");
				}
			}
		}
	}

	/**
	 * 功能:追加执行数据库操作用的SQL语句
	 * 
	 * @param sql - SQL文
	 * @return SQL语句拼接类
	 */
	public QuerySQL addSql(String sql) {
		if (this.sql == null) {
			this.sql = new StringBuilder(sql);
		} else {
			this.sql.append(sql);
		}
		return this;
	}

	/**
	 * 功能:返回执行数据库操作用的SQL语句的排序部分
	 * 
	 * @return 排序参数
	 */
	public List<String[]> getOrderBy() {
		return orderby;
	}

	/**
	 * 功能:设置执行数据库操作用的SQL语句的排序部分
	 * 
	 * @param propertyName - 类的属性名称
	 */
	public void addOrderby(String propertyName) {
		propertyName = propertyName.trim();
		int index = propertyName.indexOf(' ');
		if (index != -1) {
			String[] arr = StringUtils.split(propertyName, ' ');
			this.orderby.add(arr);
		} else {
			String[] arr = new String[2];
			arr[0] = propertyName;
			this.orderby.add(arr);
		}
	}

	/**
	 * 功能:设置执行数据库操作用的SQL语句的排序部分
	 * 
	 * @param propertyName - 类的属性名称
	 * @param orderby      - 排序类型
	 */
	public void addOrderby(String propertyName, String orderby) {
		String[] arr = new String[2];
		arr[0] = propertyName;
		arr[1] = orderby;
		this.orderby.add(arr);
	}

	/**
	 * 功能:设置数据库操作用的参数
	 * 
	 * @param list - 参数列表
	 */
	public void setParameters(List<Object> list) {
		this.list = list;
	}

	/**
	 * 功能:添加数据库操作用的参数
	 * 
	 * @param parameter - 参数
	 */
	public void addParameter(Object parameter) {
		this.list.add(parameter);
	}

	/**
	 * 功能:返回执行数据库批量操作用的参数
	 * 
	 * @return 数据库执行SQL文的对应参数列表
	 */
	public List<Object> getParameterList() {
		return this.list;
	}

	/**
	 * 功能:清空执行数据库批量操作用的参数列表
	 */
	public void clearParameterList() {
		this.list.clear();
	}

	/**
	 * 功能:返回数据库操作用的分页参数
	 * 
	 * @return 分页参数
	 */
	public PageBean getPage() {
		return page;
	}

	/**
	 * 功能:设置数据库操作用的分页参数
	 * 
	 * @param page - 分页参数
	 */
	public void setPage(PageBean page) {
		this.page = page;
	}

	/**
	 * 功能:返回数据库名
	 * 
	 * @return 数据库名
	 */
	public String getDatabaseName() {
		return databaseName;
	}

	/**
	 * 功能:设置数据库名
	 * 
	 * @param databaseName - 数据库名
	 */
	public void setDatabaseName(String databaseName) {
		this.databaseName = databaseName;
	}

	/**
	 * 功能:返回实体类型
	 * 
	 * @return 实体类型
	 */
	public Class<?> getEntityClass() {
		return entityClass;
	}

	/**
	 * 功能:设置实体类型
	 * 
	 * @param entityClass - 实体类型
	 */
	public void setEntityClass(Class<?> entityClass) {
		if (entityClass == null) {
			this.entityClass = null;
			this.tableName = null;
			return;
		}
		this.entityClass = entityClass;
		Table table = entityClass.getAnnotation(Table.class);
		if (table != null) {
			this.tableName = table.name();
		}
	}

	/**
	 * 功能:返回数据库表名
	 * 
	 * @return 数据库表名
	 */
	public String getTableName() {
		return this.tableName;
	}

	/**
	 * 功能:设置数据库表名
	 * 
	 * @param tableName - 数据库表名
	 */
	public void setTableName(String tableName) {
		this.tableName = tableName;
	}

	/**
	 * 功能:从数据实体类的注解中获取数据库表定义的元数据类
	 * <p>
	 * 先从缓存中获取，如果不存在就实时生成
	 * 
	 * @return 数据库表定义元数据类
	 */
	public TableBean getTableBean() {
		Table table = null;
		TableBean bean = null;
		if (entityClass != null) {
			table = entityClass.getAnnotation(Table.class);
		}
		if (table != null) {
			// 如果有指定实体类，就用指定的实体类封装数据
			bean = Service.getTableBean(table.name());
			if (this.tableName == null) {
				// 如果没有指定表名，则用实体类定义的表名
				this.tableName = table.name();
			}
		} else {
			// 如果有指定实体类，就用指定的表名去找实体类
			bean = Service.getTableBean(this.tableName);
		}
		return bean;
	}

	/**
	 * 功能:取得分页查询总记录数SQL语句
	 * 
	 * @return 分页查询总记录数SQL语句
	 */
	public String getCountSql() {
		int index = sql.indexOf(" from");
		int index2 = sql.lastIndexOf(" from");
		if (index == -1) {
			index = sql.indexOf(" FROM");
			index2 = sql.lastIndexOf(" FROM");
		}
		String countSql = null;
		String type = service.getDatabaseType();
		// 如果当前数据库是Mysql
		if (type.equals("mysql")) {
			// 如果只有一个from的简单查询语句
			if (index == index2) {
				countSql = "SELECT COUNT(0) " + sql.substring(index);
				index = countSql.indexOf("ORDER BY");
				if (index == -1) {
					index = countSql.indexOf("order by");
				}
				if (index != -1) {
					countSql = countSql.substring(0, index);
				}
			}
			// 如果有多个from的复杂查询语句
			else {
				countSql = "SELECT COUNT(0) from (" + sql + ')';
			}
			int begin = page.getPageIndex(); // 从第一页开始计数，第一页是0*页数
			begin = begin < 0 ? 0 : begin;
			this.sql.append(" LIMIT " + begin * page.getPageSize() + ',' + page.getPageSize());
		}
		// 如果当前数据库是postgre
		else if (type.equals("pgsql")) {
			// 如果只有一个from的简单查询语句
			if (index == index2) {
				countSql = "SELECT COUNT(0) " + sql.substring(index);
				index = countSql.indexOf("ORDER BY");
				if (index == -1) {
					index = countSql.indexOf("order by");
				}
				if (index != -1) {
					countSql = countSql.substring(0, index);
				}
			}
			// 如果有多个from的复杂查询语句
			else {
				countSql = "SELECT COUNT(0) from (" + sql + ')';
			}
			int begin = page.getPageIndex(); // 从第一页开始计数，第一页是0*页数
			begin = begin < 0 ? 0 : begin;
			this.sql.append(" LIMIT " + page.getPageSize() + " OFFSET " + begin * page.getPageSize());
		}
		// 如果当前数据库是sqlserver
		else if (type.equals("sqlserver")) {
			// 如果只有一个from的简单查询语句
			if (index == index2) {
				int i = this.sql.indexOf("ORDER BY");
				i = i == -1 ? this.sql.indexOf("order by") : i;
				if (i == -1) {
					throw new RoseRuntimeException("sqlserver数据库分页查询必须提供ORDER BY参数...");
				}
				String orderby = this.sql.substring(i);
				this.sql.delete(i, this.sql.length());
				countSql = "SELECT COUNT(0) " + sql.substring(index);
				// SELECT * FROM (SELECT *,ROW_NUMBER() OVER(ORDER BY ID ASC) AS
				// rowid FROM sys_user)t WHERE t.rowid > 10 AND t.rowid <= 20
				int begin = page.getPageIndex(); // 从第一页开始计数，第一页是0*页数
				begin = begin < 0 ? 0 : begin;
				begin = begin * page.getPageSize();
				this.sql.insert(index, ",ROW_NUMBER() OVER(" + orderby + ") AS rowid");
				this.sql.insert(0, "SELECT * FROM (");
				this.sql.append(")t WHERE t.rowid>");
				this.sql.append(begin);
				this.sql.append(" AND t.rowid <=");
				this.sql.append(begin + page.getPageSize());
				index = countSql.indexOf("ORDER BY");
				if (index != -1) {
					countSql = countSql.substring(0, index);
				}
			}
			// 如果有多个from的复杂查询语句
			else {
				countSql = "SELECT COUNT(0) from (" + sql + ')';
			}
		}
		return countSql;
	}

	/**
	 * 功能:创建通用的SQL语句
	 * 
	 * @param data - 查询参数
	 */
	public void createSql(Map<String, Object> data) {
	}

	/**
	 * 功能:添加查询条件SQL语句
	 * 
	 * @param sql  - SQL语句
	 * @param data - 参数对象
	 */
	public void addConditionSql(String sql, Map<String, Object> data) {
		String key = null;
		StringBuilder sb = new StringBuilder(sql);
		int i = sb.indexOf("#");
		if (i == -1) {
			return;
		}
		int j = sb.indexOf("#", i + 1);
		do {
			key = sb.substring(i + 1, j);
			list.add(data.get(key));
			sb.replace(i, j + 1, "?");
			i = sb.indexOf("#");
			j = sb.indexOf("#", i + 1);
		} while (i != -1 && j != -1);
		i = this.sql.indexOf(" where ");
		if (i == -1) {
			i = this.sql.indexOf(" WHERE ");
		}
		if (i == -1) {
			this.addSql(" WHERE ");
		} else {
			this.addSql(" AND ");
		}
		this.addSql(sb.toString());
	}

	/**
	 * 功能:拼装查找数据库某表符合条件的记录集合的条件SQL语句
	 * <p>
	 * 1.根据表结构的定义meta，从map集合中找出相关的表字段值作为查询参数
	 * <p>
	 * 2.如果字段类型是文本、数字或日期，则根据辅助判断参数拼接SQL条件语句
	 * <p>
	 * 3.示例：表名：user
	 * <p>
	 * 字段：userName 字符串；age 数字；birthday 日期；
	 * <p>
	 * Map<String, Object> map = new HashMap<String, Object>();
	 * <p>
	 * map.put("userName", "fgg");
	 * <p>
	 * map.put("userName_link", "like");
	 * <p>
	 * map.put("age_from", 20);
	 * <p>
	 * map.put("age_to", 40);
	 * <p>
	 * map.put("age_from_link", ">=");
	 * <p>
	 * map.put("age_to_link", "<=");
	 * <p>
	 * map.put("birthday_format", "yyyy-MM-dd");
	 * <p>
	 * map.put("birthday_from", "2013-06-25");
	 * <p>
	 * map.put("birthday_to", "2014-06-25");
	 * <p>
	 * 结果sql输出：select * from user where userName like ? and （age>? and age<=?) and
	 * (birthday>=? and birthday<=?)
	 * <p>
	 * 查询参数："fgg%"，20，20, "2013-06-25"，"2014-06-25"
	 * 
	 * @param map - 数据参数
	 * @return 条件字符串
	 */
	public void createConditionSql(Map<String, Object> map) {
		String sql = this._createConditionSql(map);
		if (!sql.equals("")) {
			int i = this.sql.indexOf(" WHERE ");
			int j = this.sql.indexOf(" where ");
			if (i != -1 || j != -1) {
				this.sql.append(" AND ");
			} else {
				this.sql.append(" WHERE ");
			}
			this.sql.append(sql);
		}
	}

	/**
	 * 功能:拼装查找数据库某表符合条件的记录集合的条件SQL语句
	 * 
	 * @param map - 数据参数
	 * @return 条件字符串
	 */
	protected String _createConditionSql(Map<String, Object> map) {
		String key = null;
		Object val = null;
		// 获取查询条件参数
		DateFormat format = new DateFormat();
		StringBuilder sb = new StringBuilder();
		TableBean table = null;
		// 如果没有设置表名，就使用实体类的表结构定义
		if (this.tableName == null) {
			table = this.getTableBean();
		}
		// 如果设置了表名，就根据表名获取表结构定义（可能是视图定义）
		else {
			table = Service.getTableBean(this.tableName);
		}
		if (map.size() > 0) {
			FieldBean pk = table.getPkField();
			boolean usePK = false;
			if (pk != null) {
				key = this.getConditionKey(pk);
				val = map.get(key);
				// 如果条件参数中含有主键值，则直接使用主键作为条件，其它不管
				if (val != null) {
					// 如果没有启用模糊查询就直接使用主键等值查询
					if (map.get(key + "_link") == null) {
						sb.append(" AND ").append(pk.getFieldName() + "=?");
						list.add(val);
						usePK = true;
					}
				}
			}
			// 如果条件参数中不含有主键值，则拼接查询条件
			if (!usePK) {
				Map<String, FieldBean> fields = table.getFieldNameFieldMap();
				for (FieldBean field : fields.values()) {
					key = this.getConditionKey(field);
					val = map.get(key);
					if (val != null) {
						// 如果是字符串类型
						if (FieldBean.isStringType(field)) {
							String fieldName = field.getFieldName();
							if (fieldName.endsWith("NAME")) {
								// 如果当前用户存在
								Object user = this.service.getUser();
								if (user != null) {
									BeanWrapper bw = new BeanWrapper();
									bw.setWrappedInstance(user);
									// 如果当前用户设置了语言
									Object lan = bw.get("language");
									if (lan != null) {
										String s = fieldName.substring(0, fieldName.length() - 4);
										s = s + lan + "NAME";
										// 如果当前字段是多国语言字段
										if (table.getFieldBeanByFieldName(s) != null) {
											fieldName = s;
										}
									}
								}
							}
							Object link = map.get(key + "_link");
							if (link != null) {
								String strLink = link.toString().trim();
								// 使用模糊查询
								if (strLink.equalsIgnoreCase("like")) {
									sb.append(" AND " + fieldName + " like ? ");
									list.add(val + "%");
								} else if (strLink.equalsIgnoreCase("like all")) {
									sb.append(" AND " + fieldName + " like ? ");
									list.add("%" + val + '%');
								} else if (strLink.equalsIgnoreCase("not like")) {
									sb.append(" AND " + fieldName + " not like ? ");
									list.add(val + "%");
								} else if (strLink.equalsIgnoreCase("not like all")) {
									sb.append(" AND " + fieldName + " not like ? ");
									list.add("%" + val + '%');
									// 使用IN查询
								} else if (strLink.equalsIgnoreCase("in")) {
									String s = val.toString();
									// 如果不是以逗号隔开的数组
									if (s.indexOf(',') == -1) {
										// 使用等值查询
										sb.append(" AND " + fieldName + "=? ");
										list.add(val);
									} else {
										// 使用IN查询
										sb.append(" AND " + fieldName + " IN(");
										for (String str : StringUtils.split(s, ',')) {
											sb.append("?,");
											list.add(str);
										}
										int len = sb.length();
										sb.replace(len - 1, len, ") ");
									}
								} else {
									// 使用比较查询
									sb.append(" AND " + fieldName + ' ' + strLink + " ? ");
									list.add(val);
								}
							} else {
								sb.append(" AND " + fieldName + "=? ");
								list.add(val);
							}
						}
						// 如果是数字类型
						else if (FieldBean.isNumberType(field)) {
							Object link = map.get(key + "_link");
							if (link != null) {
								// 使用比较查询
								sb.append(" AND " + field.getFieldName() + ' ' + link.toString().trim() + " ? ");
							} else {
								sb.append(" AND " + field.getFieldName() + "=? ");
							}
							String javaType = field.getJavaType();
							if (javaType.equals(ConstantCode.JAVA_TYPE_INTEGER)) {
								val = Integer.parseInt(val.toString());
							} else if (javaType.equals(ConstantCode.JAVA_TYPE_LONG)) {
								val = Long.parseLong(val.toString());
							} else if (javaType.equals(ConstantCode.JAVA_TYPE_DOUBLE)) {
								val = Double.parseDouble(val.toString());
							} else if (javaType.equals(ConstantCode.JAVA_TYPE_BIGDECIMAL)) {
								val = new BigDecimal(val.toString());
							}
							list.add(val);
						} else {
							sb.append(" AND " + field.getFieldName() + "=? ");
							list.add(val);
						}
					}
					// 如果还是没有取到值，可能是日期查询区间条件
					else {
						// 如果是日期类型
						if (FieldBean.isDateType(field)) {
							// 获取日期格式
							String key_format = key + "_format";
							Object obj = map.get(key_format);
							if (obj != null) {
								format.setDatePattern(obj.toString());
							}
							// 尝试取开始日期
							String key_fr = key + "_from";
							Object frVal = map.get(key_fr);
							if (frVal != null) {
								frVal = format.format(frVal.toString());
							}
							// 尝试取结束日期
							String key_to = key + "_to";
							Object to_Val = map.get(key_to);
							if (to_Val != null) {
								to_Val = format.formatEndDate(to_Val.toString());
							}
							// 拼接日期比较查询SQL语句
							if (frVal != null || to_Val != null) {
								String fromLink, toLink;
								obj = map.get(key + "_from_link");
								fromLink = obj == null ? ">=" : obj.toString();
								obj = map.get(key + "_to_link");
								toLink = obj == null ? "<" : obj.toString();
								sb.append(" AND(");
								if (frVal != null) {
									sb.append(field.getFieldName()).append(fromLink).append("? ");
									list.add(frVal);
									if (to_Val != null) {
										sb.append(" AND ").append(field.getFieldName()).append(toLink).append("? ");
										list.add(to_Val);
									}
								} else {
									if (to_Val != null) {
										sb.append(field.getFieldName()).append(toLink).append("? ");
										list.add(to_Val);
									}
								}
								sb.append(") ");
							}
							// 如果没有取到值，又是强制要查询的条件
							else if (map.get(key + "_force") != null) {
								sb.append(" AND ").append(field.getFieldName()).append(" is null ");
							}
						}
						// 如果是其它类型，如字符串或整型
						else {
							String key_fr = key + "_from";
							String key_to = key + "_to";
							Object frVal = map.get(key_fr);
							Object to_Val = map.get(key_to);
							// 如果整型
							if (FieldBean.isIntegerType(field)) {
								if (frVal != null) {
									frVal = Integer.parseInt(frVal.toString());
								}
								if (to_Val != null) {
									to_Val = Integer.parseInt(to_Val.toString());
								}
							}
							// 如果是长整型
							else if (FieldBean.isLongType(field)) {
								if (frVal != null) {
									frVal = Long.parseLong(frVal.toString());
								}
								if (to_Val != null) {
									to_Val = Long.parseLong(to_Val.toString());
								}
							}
							// 拼接比较查询SQL语句
							if (frVal != null || to_Val != null) {
								String fromLink, toLink;
								Object obj = map.get(key + "_from_link");
								fromLink = obj == null ? ">=" : obj.toString();
								obj = map.get(key + "_to_link");
								toLink = obj == null ? "<" : obj.toString();
								sb.append(" AND(");
								if (frVal != null) {
									sb.append(field.getFieldName()).append(fromLink).append("? ");
									list.add(frVal);
									if (to_Val != null) {
										sb.append(" AND ").append(field.getFieldName()).append(toLink).append("? ");
										list.add(to_Val);
									}
								} else {
									if (to_Val != null) {
										sb.append(field.getFieldName()).append(toLink).append("? ");
										list.add(to_Val);
									}
								}
								sb.append(") ");
							}
							// 如果没有取到值，又是强制要查询的条件
							else if (map.get(key + "_force") != null) {
								sb.append(" AND ").append(field.getFieldName()).append(" is null ");
							}
						}
					}
				}
			}
		}
		String condition = "";
		// 如果有条件参数
		if (sb.length() > 0) {
			String str = sb.toString().trim();
			if (str.startsWith("AND ") || str.startsWith("AND(")) {
				str = str.substring(3);
			}
			condition = str;
		}
		// 如果有排序
		val = map.get("orderBy");
		if (val != null) {
			int i = 0;
			// 如果是根据单个字段排序
			if (val instanceof String) {
				String str = val.toString();
				i = str.indexOf(',');
				if (i != -1) {
					this.addOrderby(str.substring(0, i), str.substring(i + 1));
				} else {
					this.addOrderby(str);
				}
			}
			// 如果是根据多个字段排序
			else {
				String[] arr = (String[]) val;
				for (String str : arr) {
					i = str.indexOf(',');
					if (i != -1) {
						this.addOrderby(str.substring(0, i), str.substring(i + 1));
					} else {
						this.addOrderby(str);
					}
				}
			}
		}
		return condition;
	}

	/**
	 * 功能:拼装查找数据库某表符合条件的记录集合的条件SQL语句
	 * <p>
	 * 1.根据表结构的定义meta，从map集合中找出相关的表字段值作为查询参数
	 * <p>
	 * 2.如果字段类型是文本、数字或日期，则根据辅助判断参数拼接SQL条件语句
	 * <p>
	 * 3.示例：表名：user
	 * <p>
	 * 字段：userName 字符串；age 数字；birthday 日期；
	 * <p>
	 * Map<String, Object> map = new HashMap<String, Object>();
	 * <p>
	 * map.put("userName", "fgg");
	 * <p>
	 * map.put("userName_link", "like");
	 * <p>
	 * map.put("age_from", 20);
	 * <p>
	 * map.put("age_to", 40);
	 * <p>
	 * map.put("age_from_link", ">=");
	 * <p>
	 * map.put("age_to_link", "<=");
	 * <p>
	 * map.put("birthday_format", "yyyy-MM-dd");
	 * <p>
	 * map.put("birthday_from", "2013-06-25");
	 * <p>
	 * map.put("birthday_to", "2014-06-25");
	 * <p>
	 * tablePrefix = t1
	 * <p>
	 * 结果sql输出：t1.userName like ? and （t1.age>? and t1.age<=?) and (t1.birthday>=?
	 * and t1.birthday<=?)
	 * <p>
	 * 查询参数："fgg%"，20，20, "2013-06-25"，"2014-06-25"
	 * 
	 * @param table       - 数据库表定义元数据
	 * @param map         - 数据参数
	 * @param tablePrefix - 条件名前缀
	 * @return 条件字符串
	 */
	public String createConditionSpecialSql(TableBean table, Map<String, Object> map, String tablePrefix) {
		String key = null;
		Object val = null;
		// 获取查询条件参数
		DateFormat format = new DateFormat();
		StringBuilder sb = new StringBuilder();
		if (map.size() > 0) {
			tablePrefix = tablePrefix + '.';
			Map<String, FieldBean> fields = table.getFieldNameFieldMap();
			for (FieldBean field : fields.values()) {
				String fieldName = field.getFieldName();
				key = this.getConditionKey(field);
				val = map.get(key);
				if (val != null) {
					// 如果是字符串类型
					if (FieldBean.isStringType(field)) {
						if (fieldName.endsWith("NAME")) {
							// 如果当前用户存在
							Object user = this.service.getUser();
							if (user != null) {
								BeanWrapper bw = new BeanWrapper();
								bw.setWrappedInstance(user);
								// 如果当前用户设置了语言
								Object lan = bw.get("language");
								if (lan != null) {
									String s = fieldName.substring(0, fieldName.length() - 4);
									s = s + lan + "NAME";
									// 如果当前字段是多国语言字段
									if (table.getFieldBeanByFieldName(s) != null) {
										fieldName = s;
									}
								}
							}
						}
						Object link = map.get(key + "_link");
						if (link != null) {
							String strLink = link.toString().trim();
							// 使用模糊查询
							if (strLink.equalsIgnoreCase("like")) {
								sb.append(" AND " + tablePrefix + fieldName + " like ? ");
								list.add(val + "%");
							} else if (strLink.equalsIgnoreCase("like all")) {
								sb.append(" AND " + tablePrefix + fieldName + " like ? ");
								list.add("%" + val + '%');
							} else if (strLink.equalsIgnoreCase("not like")) {
								sb.append(" AND " + tablePrefix + fieldName + " not like ? ");
								list.add(val + "%");
							} else if (strLink.equalsIgnoreCase("not like all")) {
								sb.append(" AND " + tablePrefix + fieldName + " not like ? ");
								list.add("%" + val + '%');
								// 使用IN查询
							} else if (strLink.equalsIgnoreCase("in")) {
								String s = val.toString();
								// 如果不是以逗号隔开的数组
								if (s.indexOf(',') == -1) {
									// 使用等值查询
									sb.append(" AND " + tablePrefix + fieldName + "=? ");
									list.add(val);
								} else {
									// 使用IN查询
									sb.append(" AND " + tablePrefix + fieldName + " IN(");
									for (String str : StringUtils.split(s, ',')) {
										sb.append("?,");
										list.add(str);
									}
									int len = sb.length();
									sb.replace(len - 1, len, ") ");
								}
							} else {
								// 使用比较查询
								sb.append(" AND " + tablePrefix + fieldName + ' ' + strLink + " ? ");
								list.add(val);
							}
						} else {
							sb.append(" AND " + tablePrefix + fieldName + "=? ");
							list.add(val);
						}
					}
					// 如果是数字类型
					else if (FieldBean.isNumberType(field)) {
						Object link = map.get(key + "_link");
						if (link != null) {
							// 使用比较查询
							sb.append(" AND " + tablePrefix + fieldName + ' ' + link.toString().trim() + " ? ");
						} else {
							sb.append(" AND " + tablePrefix + fieldName + "=? ");
						}
						String javaType = field.getJavaType();
						if (javaType.equals(ConstantCode.JAVA_TYPE_INTEGER)) {
							val = Integer.parseInt(val.toString());
						} else if (javaType.equals(ConstantCode.JAVA_TYPE_LONG)) {
							val = Long.parseLong(val.toString());
						} else if (javaType.equals(ConstantCode.JAVA_TYPE_DOUBLE)) {
							val = Double.parseDouble(val.toString());
						} else if (javaType.equals(ConstantCode.JAVA_TYPE_BIGDECIMAL)) {
							val = new BigDecimal(val.toString());
						}
						list.add(val);
					} else {
						sb.append(" AND " + tablePrefix + fieldName + "=? ");
						list.add(val);
					}
				}
				// 如果还是没有取到值，可能是日期查询区间条件
				else {
					// 如果是日期类型
					if (FieldBean.isDateType(field)) {
						// 获取日期格式
						String key_format = key + "_format";
						Object obj = map.get(key_format);
						if (obj != null) {
							format.setDatePattern(obj.toString());
						}
						// 尝试取开始日期
						String key_fr = key + "_from";
						Object frVal = map.get(key_fr);
						if (frVal != null) {
							frVal = format.format(frVal.toString());
						}
						// 尝试取结束日期
						String key_to = key + "_to";
						Object to_Val = map.get(key_to);
						if (to_Val != null) {
							to_Val = format.formatEndDate(to_Val.toString());
						}
						// 拼接日期比较查询SQL语句
						if (frVal != null || to_Val != null) {
							String fromLink, toLink;
							obj = map.get(key + "_from_link");
							fromLink = obj == null ? ">=" : obj.toString();
							obj = map.get(key + "_to_link");
							toLink = obj == null ? "<" : obj.toString();
							sb.append(" AND(");
							if (frVal != null) {
								sb.append(tablePrefix + fieldName).append(fromLink).append("? ");
								list.add(frVal);
								if (to_Val != null) {
									sb.append(" AND ").append(tablePrefix + fieldName).append(toLink).append("? ");
									list.add(to_Val);
								}
							} else {
								if (to_Val != null) {
									sb.append(tablePrefix + fieldName).append(toLink).append("? ");
									list.add(to_Val);
								}
							}
							sb.append(") ");
						}
						// 如果没有取到值，又是强制要查询的条件
						else if (map.get(key + "_force") != null) {
							sb.append(" AND ").append(tablePrefix + fieldName).append(" is null ");
						}
					}
					// 如果是其它类型，如字符串或整型
					else {
						String key_fr = key + "_from";
						String key_to = key + "_to";
						Object frVal = map.get(key_fr);
						Object to_Val = map.get(key_to);
						// 如果整型
						if (FieldBean.isIntegerType(field)) {
							if (frVal != null) {
								frVal = Integer.parseInt(frVal.toString());
							}
							if (to_Val != null) {
								to_Val = Integer.parseInt(to_Val.toString());
							}
						}
						// 如果是长整型
						else if (FieldBean.isLongType(field)) {
							if (frVal != null) {
								frVal = Long.parseLong(frVal.toString());
							}
							if (to_Val != null) {
								to_Val = Long.parseLong(to_Val.toString());
							}
						}
						// 拼接比较查询SQL语句
						if (frVal != null || to_Val != null) {
							String fromLink, toLink;
							Object obj = map.get(key + "_from_link");
							fromLink = obj == null ? ">=" : obj.toString();
							obj = map.get(key + "_to_link");
							toLink = obj == null ? "<" : obj.toString();
							sb.append(" AND(");
							if (frVal != null) {
								sb.append(tablePrefix + fieldName).append(fromLink).append("? ");
								list.add(frVal);
								if (to_Val != null) {
									sb.append(" AND ").append(tablePrefix + fieldName).append(toLink).append("? ");
									list.add(to_Val);
								}
							} else {
								if (to_Val != null) {
									sb.append(tablePrefix + fieldName).append(toLink).append("? ");
									list.add(to_Val);
								}
							}
							sb.append(") ");
						}
						// 如果没有取到值，又是强制要查询的条件
						else if (map.get(key + "_force") != null) {
							sb.append(" AND ").append(tablePrefix + fieldName).append(" is null ");
						}
					}
				}
			}

		}
		String condition = "";
		// 如果有条件参数
		if (sb.length() > 0) {
			String str = sb.toString().trim();
			if (str.startsWith("AND ") || str.startsWith("AND(")) {
				str = str.substring(3);
			}
			condition = str;
		}
		// 如果有排序
		val = map.get("orderBy");
		if (val != null) {
			int i = 0;
			// 如果是根据单个字段排序
			if (val instanceof String) {
				String str = val.toString();
				i = str.indexOf(',');
				if (i != -1) {
					this.addOrderby(str.substring(0, i), str.substring(i + 1));
				} else {
					this.addOrderby(str);
				}
			}
			// 如果是根据多个字段排序
			else {
				String[] arr = (String[]) val;
				for (String str : arr) {
					i = str.indexOf(',');
					if (i != -1) {
						this.addOrderby(str.substring(0, i), str.substring(i + 1));
					} else {
						this.addOrderby(str);
					}
				}
			}
		}
		return condition;
	}

	/**
	 * 功能:返回从Map中获取字段的名称 BeanSQL用的是propertyName，MapSQL用的是fieldName
	 * 
	 * @param field - 字段的定义
	 * @return 字段名称
	 */
	public String getConditionKey(FieldBean field) {
		return null;
	}

	/**
	 * 功能:返回数据库操作的执行者
	 * 
	 * @return 数据库操作的执行者
	 */
	public DbUserBean getUser() {
		return this.service.getUser();
	}

	/** 数据库服务类 */
	protected Service service = null;

	/**
	 * 功能:设置数据库服务类
	 * 
	 * @param service - 数据库服务类
	 */
	public void setService(Service service) {
		this.service = service;
	}

	/**
	 * 功能:拼装SQL日志语句
	 * 
	 * @return SQL日志语句
	 */
	public String getLog() {
		String sql = this.getSql();
		java.util.List<Object> list = this.getParameterList();
		if (list == null || list.size() == 0) {
			return sql;
		}
		if (list.get(0) instanceof Object[]) {
			return getBatchLog(sql, list);
		}
		for (Object obj : list) {
			if (obj == null) {
				sql = StringUtils.replaceOnce(sql, "?", "null");
			} else {
				String val = null;
				Class<?> en = obj.getClass();
				val = obj.toString();
				if (en == String.class) {
					val = "'" + val + '\'';
				} else if (en == Date.class) {
					val = DateFormat.format((Date) obj, DateFormat.DATE_FORMAT_3);
					val = "'" + val + '\'';
				}
				sql = StringUtils.replaceOnce(sql, "?", val);
			}
		}
		return getUserLog(sql);
	}

	/**
	 * 功能:拼装SQL日志语句(包括null)
	 * 
	 * @return SQL日志语句
	 */
	public String getLogAll() {
		String sql = this.getSql();
		java.util.List<Object> list = this.getParameterList();
		if (list == null || list.size() == 0) {
			return sql;
		}
		String val = null;
		for (Object obj : list) {
			if (obj == null) {
				val = "null";
			} else {
				Class<?> en = obj.getClass();
				val = obj.toString();
				if (en == String.class) {
					val = "'" + val + '\'';
				} else if (en == Date.class) {
					val = DateFormat.format((Date) obj, DateFormat.DATE_FORMAT_3);
					val = "'" + val + '\'';
				}
			}
			sql = StringUtils.replaceOnce(sql, "?", val);
		}
		return getUserLog(sql);
	}

	/**
	 * 功能:拼装SQL批处理日志语句
	 */
	private String getBatchLog(String sql, java.util.List<Object> list) {
		if (list == null || list.size() == 0) {
			return sql;
		}
		int index;
		String val = null;
		StringBuilder buf = null;
		StringBuilder logBuf = new StringBuilder();
		for (Object obj : list) {
			Object[] arr = (Object[]) obj;
			buf = new StringBuilder(sql);
			for (int i = 0; i < arr.length; i++) {
				index = buf.indexOf("?");
				if (arr[i] != null) {
					Class<?> en = arr[i].getClass();
					val = arr[i].toString();
					if (en == String.class) {
						val = "'" + val + '\'';
					} else if (en == Date.class) {
						val = DateFormat.format((Date) arr[i], DateFormat.DATE_FORMAT_3);
						val = "'" + val + '\'';
					}
				} else {
					val = "null";
				}
				buf.replace(index, index + 1, val);
			}
			logBuf.append(buf.toString()).append("\n");
		}
		return getUserLog(logBuf.toString());
	}

	/**
	 * SQL语句日志中加入操作人姓名
	 * 
	 * @param sql
	 * @return
	 */
	private String getUserLog(String sql) {
		String userName = null;
		Object user = this.getUser();
		if (user != null) {
			BeanWrapper bw = new BeanWrapper(user);
			Object obj = bw.get("userName");
			if (obj != null) {
				userName = obj.toString();
			}
		}
		sql = ",sql=" + sql;
		return userName != null ? "username:" + userName + sql : sql;
	}

	/**
	 * 添加数据授权过滤条件
	 */
	public void addDataAuthorFilter() {
		String str = this.getDataAuthorFilter();
		if (str == null || str.equals("")) {
			return;
		}
		int index = this.sql.indexOf(" where ");
		if (index == -1) {
			index = this.sql.indexOf(" WHERE ");
		}
		if (index == -1) {
			this.sql.append(" where ");
		} else {
			this.sql.append(" and ");
		}
		this.sql.append(str);
	}

	/**
	 * 获取数据授权过滤条件
	 */
	public String getDataAuthorFilter() {
		// 如果前端没有上传页面编号，那么不需要根据用户过滤数据
		if (this.service.getPageID() == null) {
			return null;
		}
		// 获取页面定义的授权角色
		DataAuthorBean power = this.service.getPagePower();
		if (power == null) {
			return null;
		}
		// 如果不启用授权功能，则不过滤数据
		if (power.getUseAuthor() != 1) {
			return null;
		}
		StringBuilder sb1 = new StringBuilder();
		TableBean table = this.getTableBean();
		DbUserBean user = this.service.getUser();
		String roles = user.getRoleIDs();
		// 如果当前用户是系统管理员，则不过滤数据
		if (roles != null && roles.indexOf("systemAdmin") != -1) {
			return null;
		}
		// 如果是部门领导又授权了部门领导，可以查看本部门的数据
		if (user.isLeader() == 1 && power.getAuthorLeader() == 1) {
			FieldBean field = table.getFieldBeanByPropertyName(ModelBean.DEPART_ID);
			if (field != null) {
				sb1.append('(').append(field.getFieldName()).append(" like \'");
				sb1.append(user.getDepartID()).append("%\')");
			}
		}
		// 如果是个人又授权了作者，可以查看自己的数据
		else if (power.getAuthorUser() == 1) {
			FieldBean field = table.getFieldBeanByPropertyName(ModelBean.CREATE_USER_ID);
			if (field != null) {
				sb1.append('(').append(field.getFieldName()).append("=\'").append(user.getUserID()).append("\')");
			}
		}
		StringBuilder sb2 = new StringBuilder('(');
		// 先查有没有对人员授权
		boolean useUserID = false;
		if (this.getUser() != null) {
			String userID = this.getUser().getUserID();
			List<String> list = power.getAuthorValueUserID(userID);
			if (list.size() > 0) {
				useUserID = true;
				for (String str : list) {
					sb2.append(power.getFieldName()).append(" like \'");
					sb2.append(str).append("%\" or ");
				}
			}
		}
		// 如果没有对人员授权，则查有没有对角色授权
		if (useUserID == false && roles != null) {
			List<String> list = power.getAuthorValueByRoles(roles);
			for (String str : list) {
				sb2.append(power.getFieldName()).append(" like \'");
				sb2.append(str).append("%\' or ");
			}
		}
		if (sb2.length() > 1) {
			sb2.delete(sb2.length() - 4, sb2.length());
			StringBuilder sb = new StringBuilder();
			sb.append('(');
			if (sb1.length() > 0) {
				sb.append(sb1.toString()).append(" or ");
			}
			sb.append(sb2.toString()).append(')');
			return sb.toString();
		}
		// 如果用户没有角色身份，则直接返回
		else {
			String str = sb1.toString();
			return str.equals("") ? "(1<>1) " : str;
		}
	}
}
